package com.yifeng.repo.micro.service.server.engine.dal.dsx;

import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.gomcarter.frameworks.base.exception.CustomException;
import com.google.common.base.Strings;
import com.yifeng.repo.base.constant.BaseConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.PatternMatchUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Created by daibing on 2024/6/21.
 */
@Slf4j
public class ProvinceCrossUserJoinTableNameHandler implements TableNameHandler {

    private final List<String> crossUserJoinExcludeProvinceDsKeys;
    private final String[] crossUserJoinProvinceTableNames;
    private final String crossUserJoinCommonUserName;
    private final Map<String, DataSourceProperty> datasource;

    public ProvinceCrossUserJoinTableNameHandler(List<String> crossUserJoinExcludeProvinceDsKeys,
                                                 List<String> crossUserJoinProvinceTableNames,
                                                 String crossUserJoinCommonUserName,
                                                 Map<String, DataSourceProperty> datasource) {
        this.crossUserJoinExcludeProvinceDsKeys = Optional.ofNullable(crossUserJoinExcludeProvinceDsKeys)
                .orElse(Collections.emptyList());
        this.crossUserJoinProvinceTableNames = Optional.ofNullable(crossUserJoinProvinceTableNames)
                .orElse(Collections.emptyList()).toArray(new String[0]);
        this.crossUserJoinCommonUserName = crossUserJoinCommonUserName;
        this.datasource = datasource;
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        // 1. 当前未做数据源切换，或者不是省库的切换，或者在排除省份Ds key列表之内，就直接返回原始表名
        String dsKey = DynamicDataSourceContextHolder.peek();
        if (Strings.isNullOrEmpty(dsKey)
                || !dsKey.startsWith(BaseConstant.DS_PROVINCE_KEY)
                || crossUserJoinExcludeProvinceDsKeys.contains(dsKey)) {
            return tableName;
        }

        // 2. 检查是否匹配省库表名规则，如果不匹配就返回：基础用户名+原始表名
        if (!PatternMatchUtils.simpleMatch(crossUserJoinProvinceTableNames, tableName)) {
            return crossUserJoinCommonUserName + BaseConstant.POINT + tableName;
        }

        // 3. 获取当前数据源配置，针对数据源组配置就获取第一个，然后返回：数据源配置用户名+原始表名
        String datasourceKey = datasource.keySet().stream()
                .filter(key -> key.startsWith(dsKey))
                .findFirst()
                .orElseThrow(() -> new CustomException("没有配置对应数据源：" + dsKey));
        DataSourceProperty dataSourceProperty = datasource.get(datasourceKey);
        return dataSourceProperty.getUsername() + BaseConstant.POINT + tableName;
    }

}
